home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / vu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-16  |  7.4 KB  |  278 lines

  1. /*      VU.H
  2.  *
  3.  * Real VU meter routines
  4.  *
  5.  * $Id: vu.c,v 1.2 1997/01/16 18:41:59 pekangas Exp $
  6.  *
  7.  * Copyright 1996,1997 Housemarque Inc.
  8.  *
  9.  * This file is part of the MIDAS Sound System, and may only be
  10.  * used, modified and distributed under the terms of the MIDAS
  11.  * Sound System license, LICENSE.TXT. By continuing to use,
  12.  * modify or distribute this file you indicate that you have
  13.  * read the license and understand and accept it fully.
  14. */
  15.  
  16. #include "lang.h"
  17. #include "mtypes.h"
  18. #include "errors.h"
  19. #include "mmem.h"
  20. #include "sdevice.h"
  21. #include "vu.h"
  22. #include "mutils.h"
  23.  
  24. RCSID(const char *vu_rcsid = "$Id: vu.c,v 1.2 1997/01/16 18:41:59 pekangas Exp $";)
  25.  
  26.  
  27.  
  28.     /* VU meter calculation block size in bytes: */
  29. #define VUBLOCK 128
  30.     /* Amount to shift right to convert from bytes to blocks:
  31.        (log2 VUBLOCK) */
  32. #define VUBSHIFT 7
  33.  
  34.  
  35. sdSample        *vuSamples;             /* VU sample information */
  36.  
  37.  
  38.  
  39.  
  40. /****************************************************************************\
  41. *
  42. * Function:     int vuInit(void);
  43. *
  44. * Description:  Initializes VU-meters, allocating room for MAXSAMPLES
  45. *               samples.
  46. *
  47. * Returns:      MIDAS error code
  48. *
  49. \****************************************************************************/
  50.  
  51. int CALLING vuInit(void)
  52. {
  53.     int         error, i;
  54.  
  55.     /* Allocate memory for sample information structures: */
  56.     if ( (error = memAlloc(MAXSAMPLES * sizeof(sdSample), (void**)
  57.         &vuSamples)) != OK )
  58.         PASSERROR(ID_vuInit)
  59.  
  60.     /* Point all sample VU information initially to NULL to mark it
  61.        unallocated: */
  62.     for ( i = 0; i < MAXSAMPLES; i++ )
  63.         vuSamples[i].sample = NULL;
  64.  
  65.     return OK;
  66. }
  67.  
  68.  
  69.  
  70.  
  71. /****************************************************************************\
  72. *
  73. * Function:     int vuClose(void);
  74. *
  75. * Description:  Uninitializes VU-meters
  76. *
  77. * Returns:      MIDAS error code
  78. *
  79. \****************************************************************************/
  80.  
  81. int CALLING vuClose(void)
  82. {
  83.     int         error, i;
  84.  
  85.     /* Deallocate all sample VU information that is still allocated: */
  86.     for ( i = 0; i < MAXSAMPLES; i++ )
  87.     {
  88.         if ( vuSamples[i].sample != NULL )
  89.         {
  90.             if ( (error = memFree(vuSamples[i].sample)) != OK )
  91.                 PASSERROR(ID_vuClose)
  92.             vuSamples[i].sample = NULL;
  93.         }
  94.     }
  95.  
  96.     /* Deallocate sample information structures: */
  97.     if ( (error = memFree(vuSamples)) != OK )
  98.         PASSERROR(ID_vuClose);
  99.  
  100.     return OK;
  101. }
  102.  
  103.  
  104.  
  105.  
  106. /****************************************************************************\
  107. *
  108. * Function:     int vuPrepare(sdSample *sample, unsigned sampleNumber);
  109. *
  110. * Description:  Prepares the VU information for a sample
  111. *
  112. * Input:        sdSample *sample        pointer to Sound Device sample
  113. *                                       structure for this sample
  114. *               unsigned sampleNumber   sample number (0 - (MAXSAMPLES-1)),
  115. *                                       usually sound device sample handle
  116. *
  117. * Returns:      MIDAS error code.
  118. *
  119. \****************************************************************************/
  120.  
  121. int CALLING vuPrepare(sdSample *sample, unsigned sampleNumber)
  122. {
  123.     sdSample    *vuSample = &vuSamples[sampleNumber];
  124.     int         error;
  125.     uchar       *src, *dest;
  126.     int         min, max;
  127.     unsigned    i, bleft;
  128.  
  129.     /* Copy sample information: */
  130.     mMemCopy(vuSample, sample, sizeof(sdSample));
  131.  
  132.     /* If there is no sample data or the sample type is unknown, mark there
  133.        is no VU-meter information for this sample and exit: */
  134.     if ( (vuSample->sampleLength == 0) || (vuSample->sampleType != smp8bit)
  135.         || (vuSample->samplePos != sdSmpConv) )
  136.     {
  137.         vuSample->sample = NULL;
  138.         return OK;
  139.     }
  140.  
  141.     /* FIXME - only 8-bit samples supported! */
  142.  
  143.     /* Allocate memory for VU information: */
  144.     if ( (error = memAlloc((vuSample->sampleLength + (VUBLOCK-1)) >> VUBSHIFT,
  145.         (void**) &vuSample->sample)) != OK )
  146.         PASSERROR(ID_vuPrepare)
  147.  
  148.     /* Point dest to destination buffer and src to sample data: */
  149.     dest = vuSample->sample;
  150.     src = sample->sample;
  151.  
  152.     bleft = sample->sampleLength;
  153.  
  154.     /* Process all VU information blocks: */
  155.     while ( bleft )
  156.     {
  157.         /* Process VUBLOCK bytes maximum: */
  158.         if ( bleft > VUBLOCK )
  159.             i = VUBLOCK;
  160.         else
  161.             i = bleft;
  162.  
  163.         /* Decrease bytes left: */
  164.         bleft -= i;
  165.  
  166.         /* Reset minimum and maximum values found: */
  167.         min = 255; max = 0;
  168.  
  169.         /* Go through all sample bytes belonging to this block to find the
  170.            minimum and maximum values: */
  171.         while ( i )
  172.         {
  173.             if ( *src < min )
  174.                 min = *src;
  175.             if ( *src > max )
  176.                 max = *src;
  177.             src++;
  178.             i--;
  179.         }
  180.  
  181.         /* Calculate VU-meter value for this block ((max-min)/4, rounded up),
  182.            and store it in *dest: */
  183.         *(dest++) = (uchar) ((max - min + 2) / 4);
  184.     }
  185.  
  186.     return OK;
  187. }
  188.  
  189.  
  190.  
  191.  
  192. /****************************************************************************\
  193. *
  194. * Function:     int vuRemove(unsigned sampleNumber);
  195. *
  196. * Description:  Removes and deallocates the VU information for a sample
  197. *
  198. * Input:        unsigned sampleNumbe    sample number
  199. *
  200. * Returns:      MIDAS error code
  201. *
  202. \****************************************************************************/
  203.  
  204. int CALLING vuRemove(unsigned sampleNumber)
  205. {
  206.     int         error;
  207.  
  208.     /* Deallocate VU information for this sample if allocated: */
  209.     if ( vuSamples[sampleNumber].sample != NULL )
  210.     {
  211.         if ( (error = memFree(vuSamples[sampleNumber].sample)) != OK )
  212.             PASSERROR(ID_vuRemove)
  213.     }
  214.  
  215.     /* Mark VU information unallocated: */
  216.     vuSamples[sampleNumber].sample = NULL;
  217.  
  218.     return OK;
  219. }
  220.  
  221.  
  222.  
  223.  
  224. /****************************************************************************\
  225. *
  226. * Function:     int vuMeter(unsigned sampleNumber, ulong rate,
  227. *                   unsigned position, unsigned volume, unsigned *meter);
  228. *
  229. * Description:  Calculates the VU-meter value (0-64) for the next 1/50th of
  230. *               a second
  231. *
  232. * Input:        unsigned sampleNumber   sample number
  233. *               ulong rate              playing rate
  234. *               unsigned position       sample playing position
  235. *               unsigned volume         playing volume (0-64)
  236. *               unsigned *meter         pointer to VU-meter value
  237. *
  238. * Returns:      MIDAS error code.
  239. *               VU-meter value (0-64) is stored in *meter
  240. *
  241. \****************************************************************************/
  242.  
  243. int CALLING vuMeter(unsigned sampleNumber, ulong rate, unsigned position,
  244.     unsigned volume, unsigned *meter)
  245. {
  246.     sdSample    *sample = &vuSamples[sampleNumber];
  247.     unsigned    clippos;
  248.  
  249.     /* Make sure that there is VU information for this sample: */
  250.     if ( (sample->sample == NULL) || (sampleNumber >= MAXSAMPLES) )
  251.     {
  252.         *meter = 0;
  253.         return OK;
  254.     }
  255.  
  256.     /* Make sure the position is inside the sample: */
  257.     if ( position >= sample->sampleLength )
  258.         clippos = sample->sampleLength - 1;
  259.     else
  260.         clippos = position;
  261.  
  262.     /* Just take the VU meter value for current block and scale it with
  263.        volume (FIXME?) */
  264.     *meter = ((unsigned) sample->sample[clippos >> VUBSHIFT]) * volume / 64;
  265.  
  266.     return OK;
  267. }
  268.  
  269.  
  270. /*
  271.  * $Log: vu.c,v $
  272.  * Revision 1.2  1997/01/16 18:41:59  pekangas
  273.  * Changed copyright messages to Housemarque
  274.  *
  275.  * Revision 1.1  1996/05/22 20:49:33  pekangas
  276.  * Initial revision
  277.  *
  278. */